#pragma once
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>
#include <cerrno>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <functional>
#include <signal.h>
#include "logMessage.hpp"
#define SEP " "
#define SEP_LEN strlen(SEP)
#define LINE_SEP "\r\n"
#define LINE_LEN strlen(LINE_SEP)
using namespace std;
// 输入型
class Request
{
public:
    Request()
    {
    }
    Request(int x, int y, char op) : _x(x), _y(y), _op(op)
    {
    }
    bool serialization(string *out)
    {
        // 序列化,化成字符串
        string x_string = to_string(_x);
        string y_string = to_string(_y);
        *out = x_string + SEP + _op + SEP + y_string;
        return true;
    }
    bool deserialization(const string &in)
    {
        // 反序列化
        auto left = in.find(SEP);
        auto right = in.rfind(SEP);
        if (left == string::npos || right == string::npos)
            return false;
        if (left == right)
            return false;
        if (right - (left + SEP_LEN) != 1)
            return false;
        // 把x和y分离出来
        string x_string = in.substr(0, left);
        string y_string = in.substr(right + SEP_LEN);
        if (x_string.empty() || y_string.empty())
            return false;
        _x = stoi(x_string);
        _y = stoi(y_string);
        _op = in[left + SEP_LEN];
        cout << "反序列化结果" << _x << " " << _y << " " << _op << endl;
        return true;
    }

public:
    int _x;
    int _y;
    char _op;
};
// 输出型
class Resposne
{
public:
    Resposne() : _exitcode(0), _result(0)
    {
    }
    // text_len \r\n exitcode \r\n result \r\n
    //化成带结构化数据
    bool serialization(string *out)
    {
        // 序列化
        string ec_string = to_string(_exitcode);
        string re_string = to_string(_result);
        *out = ec_string + LINE_SEP + re_string;
        return true;
    }
    bool deserialization(const string &in)
    {
        // 反序列化，把字符串化成数字
        auto pos = in.find(LINE_SEP);
        if (pos == string::npos)
            return false;
        string ec_string = in.substr(0, pos);
        string re_string = in.substr(pos + LINE_LEN);
        if (ec_string.empty() || re_string.empty())
            return false;
        _exitcode = stoi(ec_string);
        _result = stoi(re_string);
        return true;
    }

public:
    int _exitcode;
    int _result;
};
string enlength(const string &text)
{
    string send_text = to_string(text.size());
    send_text += LINE_SEP;
    send_text += text;
    send_text += LINE_SEP;
    return send_text;
}
// 除去头尾的分隔符
bool delength(const string package, string *text)
{
    auto pos = package.find(LINE_SEP);
    if (pos == string::npos)
        return false;
    int text_len = stoi(package.substr(0, pos));
    *text = package.substr(pos + LINE_LEN, text_len);
    return true;
}
//"contest_len\r\n package \r\n"
// 将输入的buffer中获取完整报文放进text里
bool GetOnePackage(string &inbuffer, string *text)
{
    // 接受分析
    auto pos = inbuffer.find(LINE_SEP);
    if (pos == string::npos)
    {
        logMessage(ERROR, "不是一个完整报文");
        return false;
    }
    string text_len_str = inbuffer.substr(0, pos);
    int text_len = stoi(text_len_str);
    // 获得package长度
    int total_len = text_len + 2 * LINE_LEN + text_len_str.size();
    if (inbuffer.size() < total_len)
    {
        logMessage(ERROR, "不是一个完整报文");
        return false;
    }
    // 报文完整
    *text = inbuffer.substr(0, total_len);
    inbuffer.erase(0, total_len);
    return true;
}